Skip to content

Async test result#549

Open
Phuong-Le-NN wants to merge 10 commits intomainfrom
async_test_res_2
Open

Async test result#549
Phuong-Le-NN wants to merge 10 commits intomainfrom
async_test_res_2

Conversation

@Phuong-Le-NN
Copy link
Collaborator

@Phuong-Le-NN Phuong-Le-NN commented Nov 26, 2025

Description

Async test result when one buddy click Run button of Leetcode

Screenshots

image

Test

Click Run code on one buddy and wait a bit to see the Test Result tab filled out on the other.

Checklist

If you're making changes to the extension, please run through the following checklist to make sure that we don't have
any regressions. Note that we plan to add integration tests in the future!

  • Create room and join room on at least 2 browsers
  • Ensure that code and tests are correctly stream
  • Verify that when reloading, user can automatically join the room

Possible Downsides

Additional Documentations

@Phuong-Le-NN Phuong-Le-NN marked this pull request as ready for review November 29, 2025 19:29
PhuongLe added 10 commits March 16, 2026 11:40
changed type to reuse test case assignment interface
fix for case when input has no variable name
backend working?
frontend not yet for error cases
fix + refactor slightly on backend for grouping test result
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use luicide-react for the icons?

s.src = chrome.runtime.getURL("proxy.js");
s.type = "text/javascript";
s.onload = () => s.remove();
document.documentElement.appendChild(s);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you clarify what this is for?

const regexTestResult =
/^https:\/\/leetcode\.com\/submissions\/detail\/runcode_[^/]+\/check\/$/;

if (typeof res.url === "string" && regexTestResult.test(res.url)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (typeof res.url === "string" && regexTestResult.test(res.url)) {
if (regexTestResult.test(res.url)) {


const origFetch = window.fetch;

window.fetch = async (...args) => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment on lines +30 to +35
{
source: "LC_HOOK",
url: res.url,
data: data,
type: "LC_HOOK",
},
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: LC_SUBMISSION_RESULT instead of LC_HOOK?

@nickbar01234
Copy link
Owner

Can you comment with the latest screenshot of the new UI?


export const getTestResultsPayload = (
variables: Question["variables"] | undefined,
testResults?: any
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be strongly typed right

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be without ? too

{
value: "testResult",
label: "Test Result",
Icon: FlaskConical,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change the icon to https://lucide.dev/icons/terminal

const passed = (test.testResult ?? []).every(
(r: ResultAssignment) => r.output === r.expected
);
const selected = !!test.selected;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary right?

return (
<div key={idx} onClick={() => selectTestResult(idx)}>
<button
className={`${baseClasses} ${selected ? selectedClasses : unselectedClasses} gap-2`}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
className={`${baseClasses} ${selected ? selectedClasses : unselectedClasses} gap-2`}
className={cn(baseClasses, { selectedClasses: selected, unselectedClasses: !selected )}

inputs: { variable?: string; value: string }[];
}

export const InputDisplay: React.FC<InputDisplayProps> = ({ inputs }) => (
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't looked through all the css yet but let's make sure the styles match with TestTab

@@ -0,0 +1,13 @@
import React from "react";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename testResultComponents to TestResults

@@ -0,0 +1,112 @@
import { SelectableTestResult } from "@cb/types";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe sharedComponents.tsx as base.tsx?

export const TEST_RESULT_ERROR = {
"Runtime Error": "full_runtime_error",
"Compile Error": "full_compile_error",
"Invalid Test Case": "full_runtime_error",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

export interface TestResult {
testResultStatus: string;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +45 to +46
testResults.code_answer?.slice(0, -1),
testResults.expected_code_answer?.slice(0, -1),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you clarify why we exclude last idx


const getLastRunIndex = () =>
codeAnswer.findIndex((val) => val !== "0") === -1
? codeAnswer.length
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't this be out of bound? Also we throw away some work with 2 findIndex

const getFirstInput = () => {
if (numCases === 0) return [];
const firstTest = testInputs[0];
if (firstTest.test.length !== varCount) return [];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of multiple checks throughout the function, how do you feel about doing all these checks upfront and returning empty list otherwise? It just makes the code easier to read if we focus only on the logic

}

// Because statusMessage of invalid test case is the same as runtime error although they are handled differently
const statusMsg: string = testResults.invalid_testcase
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


export const getTestResultsPayload = (
variables: Question["variables"] | undefined,
testResults?: any
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you be able to paste a couple examples of what testResults is for each of the cases you're targeting?

);
const overallStatus = allMatch ? "Accepted" : "Wrong Answer";

// Only loop for Accepted cases
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this loops for everything though right

});
}

return results.length > 0 ? results : [{ testResultStatus, testResult: [] }];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should always be able to return just results?

};

return (
<SkeletonWrapper loading={false} className="relative">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wrap this in error boundary? https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary. Reasoning is that this feature is quite complex with a lot of array indexing and handling, so we don't want to break other working components


export type TestCases = TestCase[];

export type TestResults = TestResult[];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, the use of TestResults is a bit inconsistent. In https://github.com/nickbar01234/codebuddy/pull/549/changes#diff-a6c0609a405d5d0726edb4d54dd9ddaab92ce2a9c7224a405da9e0bda60b5d61R32, runtime errors return 1-item list. For cases where we run the tests, the length matches the number of test input, with each TestResult.testResult being 1 element.

It looks to me like we actually just need TestResult to capture everything

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants